
package com.wfh.mianshiji.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wfh.mianshiji.common.ErrorCode;
import com.wfh.mianshiji.exception.BusinessException;
import com.wfh.mianshiji.model.vo.UserVo;
import com.wfh.mianshiji.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.Map;

/**
 * @author fenghuanwang
 */
@Slf4j
@Component
public class InterviewHandshakeInterceptor implements HandshakeInterceptor {

    @Resource
    private JwtUtil jwtUtil;

    @Override
    public boolean beforeHandshake(
            ServerHttpRequest request,
            ServerHttpResponse response,
            WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {

        log.info("有新的连接");
        if (!(request instanceof ServletServerHttpRequest servletRequest)) {
            return false;
        }

        var params = servletRequest.getServletRequest().getParameterMap();

        // 获取 interviewId（必填）
        String[] interviewIdArr = params.get("interviewId");
        if (interviewIdArr == null || interviewIdArr.length == 0) {
            log.warn("缺少 interviewId 参数");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String interviewIdStr = interviewIdArr[0];

        // 获取 token（可选但需校验）
        String[] tokenArr = params.get("token");
        String token = (tokenArr != null && tokenArr.length > 0) ? tokenArr[0] : null;
        if (token == null || !jwtUtil.validateToken(token)) {
            log.warn("token 无效或缺失");
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }

        // 解析 JWT
        Claims claims = jwtUtil.parseToken(token);
        ObjectMapper objectMapper = new ObjectMapper();
        // 3. 手动转换 user claim 为 UserVo
        Object userClaim = claims.get("user");
        if (userClaim == null) {
            return false;
        }

        UserVo userVo;
        try {
            // 关键：手动转换 LinkedHashMap -> UserVo
            userVo = objectMapper.convertValue(userClaim, UserVo.class);
        } catch (Exception e) {
            // 转换失败，拒绝握手
            System.err.println("Failed to convert user claim to UserVo: " + e.getMessage());
            return false;
        }

        // 将用户信息存入 attributes，后续 WebSocketHandler 可用
        attributes.put("userId", userVo.getId());
        Long interviewId = Long.valueOf(interviewIdStr);
        attributes.put("interviewId", interviewId);

        log.info("WebSocket 握手成功：userId={}, interviewId={}", userVo.getId(), interviewIdStr);
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

    }
}